home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / roff4.arc / ROFF46.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-08-08  |  10.9 KB  |  352 lines

  1. /********************************************************/
  2. /*                                                      */
  3. /*                  ROFF4, Version 1.60                 */
  4. /*                                                      */
  5. /*(C) 1983,4 by Ernest E. Bergmann                      */
  6. /*              Physics, Building #16                   */
  7. /*              Lehigh Univerisity                      */
  8. /*              Bethlehem, Pa. 18015                    */
  9. /*                                                      */
  10. /* Permission is hereby granted for all commercial and  */
  11. /* non-commercial reproduction and distribution of this */
  12. /* material provided this notice is included.           */
  13. /*                                                      */
  14. /********************************************************/
  15. /*Jan 14, 1984*/
  16.  
  17. #include "roff4.h"
  18. /**************************************************/
  19. int value(base,string)  /*unsigned conversion*/
  20. int base;               /*radix for conversion*/
  21. char *string;           /*no leading blanks please!*/
  22. /*trailing whitespace or '\0'*/
  23. {
  24.       int val,d;
  25.       char c;
  26.       val=0;
  27.       for(d=digit(*string);d>=0 && d<base ; d=digit(*string))
  28.       {
  29.             val = val*base + d;
  30.             string++;
  31.       }
  32.       c=*string;
  33.       if(!c || c==' ' || c==TAB || c=='\n') return(val);
  34.       else return(-1);        /*error return is -1*/
  35. }
  36. /**************************************************/
  37. int digit(d)
  38. char d;
  39. {       
  40.       d=toupper(d);
  41.       if(d<='9') return(d-'0');
  42.       if(d<'A') return(-1); /*error return is negative val*/
  43.       if(d<='Z') return(10-'A'+d);
  44.       return(-1);     /*error*/
  45. }
  46. /**************************************************/
  47. strln3(s,word,num)
  48. /*returns printed string length; checks legality of
  49.                 word function;keeps track of vertical
  50.                 excursions; records them in globals*/
  51. char *s;
  52. int word;       /* boolean, if true, check is made for none
  53.                 black characters in the string*/
  54. int num;        /* for expansion of NUMSIGN;set 1 to ignore*/
  55. {
  56.       int i,i2,p1,p2,p3;
  57.       int t,b,h;      /*vertical vars*/
  58.       char c, *ss;
  59.       ss=s;
  60.       t=b=h=0;
  61.       p3=p2=p1=-LSZ;
  62.       for(c=*s,i2=i=0;c;c=*(++s))
  63.       {
  64.             if(c==NUMSIGN)
  65.             {
  66.                   i++;
  67.                   if(num>9) i++;
  68.                   if(num>99) i++;
  69.                   if(num>999) i++;
  70.             }
  71.             else if((c!=TCVAL)&&(c!=CFVAL))
  72.             {
  73.                   if((c<=' ')&&(word)) goto error;
  74.                   else i++;
  75.             }
  76.             else if(c==CFVAL)
  77.             {
  78.                   c=*(++s);
  79.                   if(c==TCVAL) goto error;/*both CFVAL,TCVAL*/
  80.                   switch(c)
  81.                   {
  82.                   case 'h':
  83.                   case 'H':
  84.                         if(i>i2) i2=i;
  85.                         if(i) i--;
  86.                         else goto error;/*before start*/
  87.                         break;
  88.                   case '+': 
  89.                         h--; 
  90.                         if(h<t) t=h; 
  91.                         break;
  92.                   case '-': 
  93.                         h++; 
  94.                         if(h>b) b=h; 
  95.                         break;
  96.                   case 'B':
  97.                   case 'b':
  98.                   case 'D':
  99.                   case 'd':
  100.                   case 'u':
  101.                   case 'U':
  102.                   case 'X':
  103.                   case 'x': 
  104.                         break;
  105.                   case '(': 
  106.                         p1=i; 
  107.                         break;
  108.                   case '[': 
  109.                         p2=i; 
  110.                         break;
  111.                   case '{': 
  112.                         p3=i; 
  113.                         break;
  114.                   case ')': 
  115.                         if(i>i2) i2=i; 
  116.                         i=p1; 
  117.                         break;
  118.                   case ']': 
  119.                         if(i>i2) i2=i; 
  120.                         i=p2; 
  121.                         break;
  122.                   case '}': 
  123.                         if(i>i2) i2=i; 
  124.                         i=p3; 
  125.                         break;
  126.                   default: 
  127.                         if(CPTR[c-' ']) break;
  128.                         goto error;     /*undecipherable*/
  129.                   }
  130.             }
  131.             else/*c==TCVAL*/
  132.             {
  133.                   if(class(*(s+1))!=BLACK)
  134.                         goto error;     /*illegal translation*/
  135.             }
  136.       }
  137.       if(h) goto error;
  138.       if(word){
  139.             WTOP=t;
  140.             WBOT=b;
  141.       }
  142.       else    {
  143.             LTOP=t;
  144.             LBOT=b;
  145.       }
  146.       if(i>=i2)return(i);
  147.       /* else prints beyond last character: */
  148. error:
  149.       /*should be fprint -> STDERR*/
  150.       fprintf(STDERR,"STRLN3:<%s> is illegally formed\n",
  151.       ss);
  152.       return(strlen(ss));
  153. }
  154. /* A properly formed token string has its first printable
  155. character indicating the lefthand edge and the last printable
  156. character at the right hand edge.  Only legal control pairs
  157. accepted.  It must consist of printable symbols. */
  158. /************************************
  159. set stack like set() sets a variable
  160. *************************************/
  161. setS(param,val,arg_typ,defval,minval,maxval)
  162. int param[STKSIZ+1],val,defval,minval,maxval;
  163. char arg_typ;
  164. {
  165.       int i;
  166.       if(val==NO_VAL)
  167.       {
  168.             for(i=0;i<STKSIZ;i++)  /*pop*/
  169.                   param[i]=param[i+1];
  170.             param[STKSIZ]=defval;
  171.       }
  172.       else    {
  173.             for(i=STKSIZ;i;i--)    /*push*/
  174.                   param[i]=param[i-1];
  175.             if (arg_typ=='+') *param+=val;
  176.             else if (arg_typ=='-') *param-=val;
  177.             else *param=val;
  178.       }
  179.       *param=min(max(*param,minval),maxval);
  180. #ifdef DEBUGON
  181.       if DEBUG fprintf(STDERR,"\n  setS: *param = %d",*param);
  182. #endif
  183. }
  184. /******************************************
  185. initialize stack type variable, st, with v
  186. *******************************************/
  187. initsk(st,v)
  188. int st[STKSIZ+1],v;
  189. {
  190.       int i;
  191.       for(i=STKSIZ+1;i;st[--i]=v);
  192. }
  193. /**************************************************/
  194. gettr() /*process .tr */
  195. {
  196.       char chr,*pchr,getcode();
  197.       char wrdbuf[MAXLINE];
  198.       getwrd(LINE,wrdbuf);    /*remove .tr*/
  199.       if(getwrd(LINE,wrdbuf)==WE_HAVE_A_WORD)chr=*wrdbuf;
  200.       else return;    /*error: missing args*/
  201.  
  202.       pchr = TREND;
  203.       if('.'==getcode())
  204.             TPTR[chr-' ']=pchr;     /*record pointer*/
  205.       else    {
  206.             TREND=pchr;
  207.             fprintf(STDERR,"\nError for .TR; error in line:\n%s\n",
  208.             LINE);
  209.       }
  210. }
  211. /**************************************************/
  212. getpc() /*process .pc, printer control */
  213. {
  214.       char chr,*pchr,getcode();
  215.       char wrdbuf[MAXLINE];
  216.       getwrd(LINE,wrdbuf);    /*remove .pc*/
  217.       if(getwrd(LINE,wrdbuf)==WE_HAVE_A_WORD)chr=*wrdbuf;
  218.       else return;    /*error: missing args*/
  219.  
  220.       pchr = TREND;
  221.       if('.'==getcode())
  222.             CPTR[chr-' ']=pchr;     /*record pointer*/
  223.       else    {
  224.             TREND=pchr;
  225.             fprintf(STDERR,"\nError for .PC; error in line:\n%s\n",
  226.             LINE);
  227.       }
  228. }
  229. /**************************************************/
  230. /*added start() and complete() to avoid contention on TRTBL*/
  231. char getcode()  /*LINE must contain the radix as the first
  232.                 token and it and the following lines then
  233.                 contain code values finally delimited by a
  234.                 token that starts with a '.' ; comments can
  235.                 be at the end of any of these lines, set off by
  236.                 " ;" */
  237. {
  238.       int base,code; /*conversion radix, value*/
  239.       char *pcode,ncode;
  240.       char wrdbuf[MAXLINE];
  241.       if(TREND>(&TRTBL[TRSIZ-128]))
  242.             fprintf(STDERR,"\nTR table full\n");
  243.       if(getwrd(LINE,wrdbuf)==WE_HAVE_A_WORD)
  244.       {
  245.             switch(toupper(*wrdbuf))
  246.             {
  247.             case 'B': 
  248.                   base=2;
  249.                   break;
  250.             case 'O':
  251.             case 'Q': 
  252.                   base=8;
  253.                   break;
  254.             case 'D': 
  255.                   base=10;
  256.                   break;
  257.             case 'H': 
  258.                   base=16;
  259.                   break;
  260.             default: 
  261.                   return(FALSE); /*error*/
  262.             }
  263. #ifdef DEBUGON
  264.             if DEBUG
  265.                 fprintf(STDERR,"\nGETCODE:radix token=<%s>,base=<%d>",
  266.             wrdbuf, base);
  267. #endif
  268.       }
  269.       else return(FALSE);     /*error: missing arg*/
  270.       start();
  271.       pcode =TREND++;
  272.       *pcode=ncode = 0;
  273.       while(ncode<127)
  274.       {
  275.             while(getwrd(LINE,wrdbuf)!=WE_HAVE_A_WORD)
  276.                   fgets2(LINE,IOBUF);
  277. #ifdef DEBUGON
  278.             if DEBUG fprintf(STDERR,"\nGETTR: next token is <%s>",
  279.             wrdbuf);
  280. #endif
  281.             if(';'==*wrdbuf) fgets2(LINE,IOBUF);/*comment*/
  282.             else if('.'==*wrdbuf)
  283.             {
  284.                   *pcode = ncode;                /*save #*/
  285.                   complete();
  286.                   return(*wrdbuf);
  287.             }
  288.             else   {
  289.                   if((code=value(base,wrdbuf)) > -1)
  290.                   {
  291.                         *(TREND++) = code;
  292.                         ncode++ ;
  293.                   }
  294.                   else {
  295.                         complete();
  296.                         return(*wrdbuf);   /*conversion error*/
  297.                   }
  298.             }
  299.       }
  300.       complete();
  301.       fprintf(STDERR,"\nGETCODE: code sequence too long");
  302.       return(FALSE);
  303. }
  304. /**************************************************/
  305. ocode() /*process .ou*/
  306. {
  307.       char wrdbuf[MAXLINE],*pcode,*p;
  308.       getwrd(LINE,wrdbuf);    /*remove .ou*/
  309.       p=pcode=TREND;
  310.       if('.'==getcode()) outstr(p);
  311.       else fprintf(STDERR,"\nOCODE: error in:\n%s\n",LINE);
  312.       TREND=pcode;
  313. }
  314. /**************************************************/
  315. outstr(p)       /*print string whose bytecount is *p */
  316. char *p;
  317. {
  318.       int i;
  319.       for(i=*(p++); i; i--) putchar(*(p++));
  320. }
  321. /**************************************************/
  322. getfr() /*process .FR ;cf. ocode() */
  323. {
  324.       char *pchr,getcode(),wrdbuf[MAXLINE];
  325.       getwrd(LINE,wrdbuf);
  326.       if(getwrd(LINE,wrdbuf)==WE_HAVE_A_WORD)
  327.             FRVAL = atoi(wrdbuf);
  328.       else return;
  329.       FRVAL=max(1,FRVAL); 
  330.       FRVAL=min(FRVAL,4);
  331.       pchr=TREND;
  332.       if('.'==getcode()) FRSTRING=pchr;
  333.       else    {
  334.             TREND = pchr;
  335.             fprintf(STDERR,"\nError for .FR in:\n%s\n",
  336.             LINE);
  337.       }
  338. }
  339. /**************************************************/
  340. getwh() /*process .WH ;cf. gettr() */
  341. {
  342.       char *pcode, getcode(), wrdbuf[MAXLINE];
  343.       getwrd(LINE,wrdbuf);
  344.       pcode = TREND;
  345.       if('.'==getcode()) WHSTRING=pcode;
  346.       else    {
  347.             TREND = pcode;
  348.             fprintf(STDERR,"\nError for .WH in:\n%s\n",
  349.             LINE);
  350.       }
  351. }
  352.